package com.example.smartstart.service.impl;

import com.example.smartstart.entity.MapPoint;
import com.example.smartstart.entity.MapRecord;
import com.example.smartstart.entity.Point;
import com.example.smartstart.entity.Student;
import com.example.smartstart.mapper.MapPointMapper;
import com.example.smartstart.mapper.MapRecordMapper;
import com.example.smartstart.mapper.PointMapper;
import com.example.smartstart.service.IMapPointService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.smartstart.utils.GeoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dlx
 * @since 2024-07-22
 */
@Service
public class MapPointServiceImpl extends ServiceImpl<MapPointMapper, MapPoint> implements IMapPointService {

    // 预设的打卡范围半径，单位：公里
    private static final double CHECKIN_RADIUS = 1.0; // 例如，1公里内可以打卡

    @Autowired
    private MapPointMapper mapPointMapper;

    @Autowired
    private MapRecordMapper mapRecordMapper;

    @Autowired
    private PointMapper pointMapper;

    @Override
    public Integer queryTotal(MapPoint mapPoint) {
        return mapPointMapper.queryTotal(mapPoint);
    }

    @Override
    public List<MapPoint> listByPage(MapPoint mapPoint) {
        return mapPointMapper.listByPage(mapPoint);
    }

    @Override
    public Integer adminQueryTotal(MapPoint mapPoint) {
        return mapPointMapper.adminQueryTotal(mapPoint);
    }

    @Override
    public List<MapPoint> adminListByPage(MapPoint mapPoint) {
        return mapPointMapper.adminListByPage(mapPoint);
    }

    @Override
    public Integer deleteMorePoint(Integer[] ids){
        return mapPointMapper.deleteBatchIds(Arrays.stream(ids).toList());
    }

    @Override
    @Transactional
    public void checkIn(MapPoint mapPoint) {


        Integer userId = 1;// token里取

        // 判断是否在点位范围内
        if (!isInCheckinRange(mapPoint.getUserLat(),mapPoint.getUserLng(),mapPoint.getLat(),mapPoint.getLng())){
            throw new MapPointServiceImpl.OutOfCheckinRangeException("不在范围内");
        }else {
            System.out.println("在范围内");
        }

        MapRecord mapRecord = new MapRecord();
        mapRecord.setCreateTime(LocalDateTime.now());
        mapRecord.setMapPointId(mapPoint.getId());
        mapRecord.setUserId(userId);

        Point point =pointMapper.selectById(userId);
        Integer havePoints = point.getPointCount();
        point.setPointCount(havePoints+mapPoint.getRewardPoints());

        try{
            // 添加记录表
            mapRecordMapper.insert(mapRecord);
            // 修改用户积分表
            pointMapper.updateById(point);
        } catch (Exception e) {
            throw new RuntimeException("执行过程中发生错误", e);
        }
    }

    /**
     * 检查用户是否在打卡范围内
     *
     * @param userLat 用户的纬度
     * @param userLng 用户的经度
     * @param lat 打卡点的纬度
     * @param lng 打卡点的经度
     * @return 如果用户在范围内，则返回true；否则返回false
     */
    public boolean isInCheckinRange(Double userLat, Double userLng, Double lat, Double lng) {
        double distance = GeoUtils.haversineDistance(userLat, userLng, lat, lng);
        return distance <= CHECKIN_RADIUS;
    }

    // 自定义运行时异常
    public static class OutOfCheckinRangeException extends RuntimeException {
        // 使用传入的消息创建异常
        public OutOfCheckinRangeException(String message) {
            super(message);
        }
    }
}
